package com.example.learnnetty.baseclass;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;

/**
 * 使用FileChannel完成文件复制的实践
 * @author ZMJ
 * @date 2020/9/10
 */
@Slf4j
public class FileChannelDemo {

    public static void main(String[] args) throws IOException {

        // 演示复制资源文件
        nioCopyResourceFile();

    }

    /**
     * 复制两个资源目录下的文件
     */
    private static void nioCopyResourceFile() {
        String srcPath = "/Users/meijia1/Downloads/test-nio-file.txt";
        String srcDecodePath = "";
        String destPath = "/Users/meijia1/Downloads/test-nio-file-copy.txt";
        String descDecodePath = "";

        nioCopyFile(srcPath, destPath);
    }


    /**
     * nio方式复制文件
     * @param srcPath
     * @param descPath
     */
    private static void nioCopyFile(String srcPath, String descPath) {

        File srcFile = new File(srcPath);
        File descFile = new File(descPath);

        long startTime = System.currentTimeMillis();
        FileInputStream fis = null;
        FileOutputStream fos = null;
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            if (!descFile.exists()) {
                descFile.createNewFile();
            }
            fis = new FileInputStream(srcFile);
            fos = new FileOutputStream(descFile);
            inChannel = fis.getChannel();
            outChannel = fos.getChannel();
            int length = -1;
            // 分配内存缓存区大小
            ByteBuffer buf = ByteBuffer.allocate(1024);

            // 从输入通道读取到buf
            while ((length = inChannel.read(buf)) != -1) {
                // 第一次切换：翻转buf,变成读取模式
                buf.flip();
                int outLength = 0;
                // 将buf写入到输出的通道
                while ((outLength = outChannel.write(buf)) != 0) {
                    System.out.println("写入的字节数：" + outLength);
                }
                // 第二次切换：清除buf，变成写入模式
                buf.clear();
            }

            // 强制刷新到磁盘
            outChannel.force(true);

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            // 关闭所有可关闭对象
            try {
                outChannel.close();
                fos.close();
                inChannel.close();
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            log.info("base复制毫秒数:" + (System.currentTimeMillis() - startTime));
        }

    }

}
